home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 7 / FM Towns Free Software Collection 7.iso / t_os / artemis / artsrc1 / sub.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-11-30  |  21.0 KB  |  979 lines

  1. /*
  2.     ARTemis (Graphic Editor for FM-TOWNS)
  3.     (c) MATSUUCHI Ryosuke 1992
  4.  
  5.     sub.c
  6.  
  7.     補助処理モジュール
  8.  
  9.  
  10.     page_menu            書き込みページをメニュー用ページに
  11.     page_edit            書き込みページを描画用ページに
  12.  
  13.     trans_fname_ext        ファイル名の拡張子を置き換える
  14.     getfsize            あるファイルの大きさを得る
  15.     resetfattr            ファイルの属性をクリアする
  16.  
  17.     cbuf_init            濃度バッファ・初期化
  18.     cbuf_clear            濃度バッファ・クリア
  19.     cbuf_adrs            濃度バッファ・指定座標のアドレス取得
  20.     cbuf_getlinesize    
  21.     cbuf_mix
  22.  
  23.     scrollForCsr        カーソル座標が画面内にくるようスクロール
  24.     limitCsrPos            カーソル座標の制限
  25.  
  26.     area_init            領域指定処理の初期化
  27.     area_input            矩形/ポリゴンによる領域の入力
  28.     area_chkxy            ある座標が、指定領域内かどうかを調べる
  29.     area_chkxy2            (x,y)-(x+1,y+1)が、指定領域内かどうかを調べる
  30.     area_chkxylen        ある座標から右に何ドット同じフラグが連続しているか
  31.     area_getboundxy        指定領域を囲む最小の矩形を得る
  32.  
  33.     hline_func            マスクされていない部分だけに描画する
  34. */
  35.  
  36. #include <stdio.h>
  37. #include <stdefs.h>
  38. #include <egb.h>
  39. #include <malloc.h>
  40. #include <stdlib.h>
  41. #include <msdos.cf>
  42. #include <memory.h>
  43. #include <interrup.cf>
  44. #include <math.h>
  45. #include <dos.h>
  46.  
  47. #include "ge.h"
  48. #include "plt16.h"
  49. #include "dispman.h"
  50. #include "imageman.h"
  51. #include "mask.h"
  52.  
  53. /*--------------------------------------------------------*/
  54. /*                     ページ切り換え                     */
  55. /*--------------------------------------------------------*/
  56.  
  57.  
  58. void page_menu()
  59. {
  60.     gwrtpage(0);
  61. }
  62.  
  63.  
  64. void page_edit()
  65. {
  66.     if (!DMgetifonepage())
  67.         gwrtpage(1);
  68.     else
  69.         gwrtpage(0);
  70. }
  71.  
  72. /*--------------------------------------------------------*/
  73. /*                 ファイルの大きさを得る                 */
  74. /*--------------------------------------------------------*/
  75.  
  76. int getfsize(char *fname)
  77. {
  78.     struct find_t dirbuf;
  79.     if (_dos_findfirst(fname, _A_NORMAL, &dirbuf) == 0)
  80.         return dirbuf.size;
  81.     else
  82.         return -1;
  83. }
  84.  
  85. /*--------------------------------------------------------*/
  86. /*               ファイルの属性をクリアする               */
  87. /*--------------------------------------------------------*/
  88.  
  89. int resetfattr(char *fname)
  90. {
  91.     if (_dos_setfileattr(fname, _A_ARCH | _A_NORMAL) == 0)
  92.         return 0;
  93.     else
  94.         return -1;
  95. }
  96.  
  97. bool fexist(char *fname)
  98. {
  99.     unsigned int b;
  100.     if (_dos_getfileattr(fname, &b) == 0)
  101.         return YES;
  102.     else
  103.         return NO;
  104. }
  105.  
  106. /*--------------------------------------------------------*/
  107. /*                       文字列操作                       */
  108. /*--------------------------------------------------------*/
  109.  
  110.  
  111. char *trans_fname_ext(char *fname, char *newext)
  112. /*
  113.     ファイル名 fname の拡張子を newext に置き換えたファイル名を返す
  114. */
  115. {
  116.     static char path_buf[_MAX_PATH];
  117.     char drive[_MAX_DRIVE], dir[_MAX_DIR], basename[_MAX_FNAME], ext[_MAX_EXT];
  118.     _splitpath(fname, drive, dir, basename, ext);
  119.     _makepath(path_buf, drive, dir, basename, newext);
  120.     return path_buf;
  121. }
  122.  
  123.  
  124. void add_fname_ext(char *buf, char *fname, char *newext)
  125. /*
  126.     ファイル名 fname に拡張子が無い場合、newext を拡張子として加える
  127. */
  128. {
  129.     char drive[_MAX_DRIVE], dir[_MAX_DIR], basename[_MAX_FNAME], ext[_MAX_EXT];
  130.     _splitpath(fname, drive, dir, basename, ext);
  131.     if (ext[0] == '\0')
  132.         _makepath(buf, drive, dir, basename, newext);
  133.     else
  134.         _makepath(buf, drive, dir, basename, ext);
  135. }
  136.  
  137.  
  138. /*--------------------------------------------------------*/
  139. /*                   濃度バッファの扱い                   */
  140. /*--------------------------------------------------------*/
  141.  
  142.  
  143. // 濃度バッファは、1ドットが1バイトに対応するバッファ。
  144. //  各バイトには、「(描画したい濃度)-1」の値(0..255)が入る。
  145. // ★★ 将来、編集バッファサイズ変更機能を加えたときはこのままではダメ
  146.  
  147.  
  148. static    char*    cbuf = NULL;
  149. static    int        cbuf_xsize,cbuf_ysize;
  150.  
  151.  
  152. int cbuf_init()
  153. {
  154.     cbuf_xsize = EIMgetxsize();
  155.     cbuf_ysize = EIMgetysize();
  156.     if ((cbuf = malloc(cbuf_xsize*cbuf_ysize)) == NULL)
  157.         return -1;
  158.     memset(cbuf,0,cbuf_xsize*cbuf_ysize);
  159.     return 0;
  160. }
  161.  
  162.  
  163. void cbuf_clear()
  164. {
  165.     memset(cbuf,0,cbuf_xsize*cbuf_ysize);
  166. }
  167.  
  168.  
  169. char *cbuf_adrs(int x, int y)
  170. {
  171.     return cbuf+y*cbuf_xsize+x;
  172. }
  173.  
  174.  
  175. int cbuf_getlinesize()
  176. {
  177.     return cbuf_xsize;
  178. }
  179.  
  180.  
  181. int cbuf_mix(int c0, int rate, int maxconc)
  182. {
  183.     int c;
  184.     if (rate == 0 || c0 >= maxconc)
  185.         return c0;
  186.     else if (rate == 256)
  187.         return maxconc;
  188.     c = (c0 * (256-rate) + maxconc * rate + 255) >> 8;
  189.     if (c == c0)
  190.         return _min(c+1,maxconc);
  191.     else
  192.         return _min(c,maxconc);
  193. }
  194.  
  195.  
  196. /*--------------------------------------------------------*/
  197. /*                       スクロール                       */
  198. /*--------------------------------------------------------*/
  199.  
  200.  
  201. void scrollForCsr(int xlen,int ylen)
  202. // (ms.x,ms.y)-len(xlen,ylen) の範囲が画面内にくるようにスクロール
  203. {
  204.     int dispx,dispy,dispxlen,dispylen;
  205.     int zr=DMimage_getzoomrate();
  206.     DMimage_getdispxy(&dispx,&dispy);
  207.     DMimage_getdispxylen(&dispxlen,&dispylen);
  208.     int pre_dispx,pre_dispy;
  209.     bool mschg;
  210.     pre_dispx = dispx, pre_dispy = dispy;
  211.     mschg = NO;
  212.     while (ms.x+xlen-1>=DMgetxsize()) {
  213.         if (dispx + dispxlen < EIMgetxsize())
  214.             ms.x -= zr,  dispx++,  mschg = YES;
  215.         else
  216.             ms.x=DMgetxsize()-xlen,  mschg = YES;
  217.     }
  218.     while (ms.x<0) {
  219.         if (dispx > 0)
  220.             ms.x += zr,  dispx--,  mschg = YES;
  221.         else
  222.             ms.x=0,  mschg = YES;
  223.     }
  224.     while (ms.y+ylen-1>=DMgetysize()) {
  225.         if (dispy + dispylen < EIMgetysize())
  226.             ms.y -= zr,  dispy++,  mschg = YES;
  227.         else
  228.             ms.y=DMgetysize()-ylen,  mschg = YES;
  229.     }
  230.     while (ms.y<0) {
  231.         if (dispy > 0)
  232.             ms.y += zr,  dispy--, mschg = YES;
  233.         else
  234.             ms.y=0,  mschg = YES;
  235.     }
  236.     if (mschg)
  237.         mous_setpos(&ms, ms.x, ms.y);
  238.     if (pre_dispx!=dispx || pre_dispy!=dispy)
  239.         DMimage_setdispxy(dispx,dispy);
  240. }
  241.  
  242.  
  243. void limitCsrPos()    // カーソルの座標の制限処理
  244. {
  245.     bool mschg = NO;
  246.     if (ms.x < 0)
  247.         ms.x = 0, mschg = YES;
  248.     else if (ms.x >= DMgetxsize())
  249.         ms.x = DMgetxsize()-1, mschg = YES;
  250.     if (ms.y < 0)
  251.         ms.y = 0, mschg = YES;
  252.     else if (ms.y > DMgetysize())
  253.         ms.y = DMgetysize()-1, mschg = YES;
  254.     if (mschg)
  255.         mous_setpos(&ms, ms.x, ms.y);
  256. }
  257.  
  258.  
  259. /*--------------------------------------------------------*/
  260. /*             矩形/ポリゴンによる領域の入力             */
  261. /*--------------------------------------------------------*/
  262.  
  263.  
  264. static char *area_buf = NULL;
  265. static bool areasizevar = NO;    // 領域指定バッファの縦横サイズが可変かどうか
  266. static int areaxlen, areaylen;    // areasizevar=YES時のバッファの縦横サイズ
  267. static int ax1,ay1,ax2,ay2;        // 指定領域を囲む最小矩形
  268. #define    XBUFMAX        10            /* 1ラインにつき、x 座標をいくつ記憶するか */
  269. #define    RIGHTMAX    0x7fff
  270. typedef short int    areapos;
  271. static areapos **xbuf = NULL;    // ポリゴン指定用ワーク
  272. #define    MAXP    1024
  273. static areapos *px=NULL,*py=NULL;  // ポリゴンの輪郭保存用
  274. static short int pnum;
  275.  
  276. #define    AREAXLEN    512
  277.  
  278. int area_init()
  279. // 返値: 0=成功  0以外=メモリ不足
  280. {
  281.     int size;
  282.     if (EIMgetxsize() <= AREAXLEN)
  283.         areasizevar = NO, areaxlen = AREAXLEN;
  284.     else
  285.         areasizevar = YES, areaxlen=(EIMgetxsize()+7)&0xffff8;
  286.     areaylen = EIMgetysize();
  287.     size = (areaxlen / 8) * areaylen;
  288.     if (area_buf == NULL)
  289.     {
  290.         if ((area_buf = calloc(1,size)) == NULL)
  291.         {
  292.             DEBUG_MSG("領域指定バッファ用メモリ領域 確保失敗");
  293.             return -1;
  294.         }
  295.         else
  296.             DEBUG_MSG("領域指定バッファ用メモリ領域 確保成功");
  297.     }
  298.     if (xbuf == NULL)
  299.     {
  300.         if ((xbuf = (areapos**)malloc(sizeof(areapos*)*areaylen)) == NULL)
  301.             return -1;
  302.         memset(xbuf, 0, sizeof(areapos*) * areaylen);
  303.     }
  304.     if (xbuf[0] == NULL) {
  305.         bool error = NO;
  306.         int i;
  307.         for (i=0; i<areaylen; i++)
  308.         {
  309.             if ((xbuf[i] = (areapos*)malloc(sizeof(areapos)*XBUFMAX)) == NULL)
  310.                 { error = YES;  break; }
  311.         }
  312.         if (error)
  313.         {
  314.             DEBUG_MSG("area_polygon 領域指定ポリゴン描画用ワーク 確保失敗");
  315.             return -1;
  316.         }
  317.         DEBUG_MSG("area_polygon 領域指定ポリゴン描画用ワーク 確保成功");
  318.     }
  319.     if (px == NULL)
  320.     {
  321.         if ((px = (areapos*)malloc(sizeof(areapos)*MAXP*2)) == NULL)
  322.             return -1;
  323.         py = px + MAXP;
  324.         pnum = 0;
  325.     }
  326.     return 0;
  327. }
  328.  
  329.  
  330. static void area_clear()
  331. {
  332.     memset(area_buf, 0, (areaxlen >> 3)*areaylen);
  333. }
  334.  
  335.  
  336. static void area_hline(int x1,int x2,int y)
  337. {
  338.     char *p;  int x,leftx,rightx,xr1,xr2;
  339.     if (x1 > x2)
  340.         swap(x1,x2);
  341.     p = area_buf + (areaxlen >> 3) * y + (x1 >> 3);
  342.     leftx = x1 & 0xfff8;
  343.     xr1 = x1 & 7;
  344.     rightx = x2 & 0xfff8;
  345.     xr2 = x2 & 7;
  346.     if (leftx == rightx)
  347.     {
  348.         *p |= (0xff << xr1) & (0xff >> (7-xr2));
  349.     }
  350.     else
  351.     {
  352.         x = leftx;
  353.         *p++ |= (0xff << xr1) & 0xff,  x += 8;    // 左端
  354.         while (x < rightx)                        // 真ん中
  355.             *p++ = 0xff,  x += 8;
  356.         *p |= (0xff >> (7-xr2));                // 右端
  357.     }
  358. }
  359.  
  360.  
  361.  
  362. static void area_polygon(areapos *xlist,areapos *ylist)
  363. {
  364.     int i;
  365.     for (i=0; i<areaylen; i++)
  366.         *xbuf[i] = RIGHTMAX;
  367.     int getsign(int n)
  368.     {
  369.         return (n<0 ? -1 : n>0 ? 1 : 0);
  370.     }
  371.     int f1,f2,pnum;
  372.     for (pnum=0; xlist[pnum]>=0; pnum++)    // 頂点の数をかぞえる
  373.         ;
  374.     // 始点での頂点の例外処理のために、前の辺の符号をきめる
  375.     f1=0;
  376.     for (i=1; i<pnum; i++) {
  377.         f2=getsign(ylist[i]-ylist[i-1]);
  378.         if (f2!=0)
  379.             f1=f2;
  380.     }
  381.     f2=getsign(ylist[0]-ylist[pnum-1]);
  382.     if (f2!=0)
  383.         f1=f2;
  384.     // x 座標リストの作成
  385.     void makebuf(int x1,int y1,int x2,int y2)
  386.     {
  387.         int xmax,ymax;
  388.         xmax = EIMgetxsize()-1;
  389.         ymax = EIMgetysize()-1;
  390.         void sort_x()        // (x1,y1) をバッファに登録する
  391.         {
  392.             if (x1<0 || xmax<x1 || y1<0 || ymax<y1)
  393.                 return;
  394.             int i;
  395.             for (i=0; i<XBUFMAX; i++)
  396.             {
  397.                 if (xbuf[y1][i] > x1)
  398.                 {
  399.                     int j;
  400.                     if (i==XBUFMAX-1)
  401.                     {
  402.                         xbuf[y1][i] = x1;
  403.                         return;
  404.                     }
  405.                     for (j=XBUFMAX-1; j>i; j--)
  406.                         xbuf[y1][j] = xbuf[y1][j-1];
  407.                     xbuf[y1][i] = x1;
  408.                     break;
  409.                 }
  410.             }
  411.         }
  412.         int f2;
  413.         f2 = getsign(y2-y1);
  414.         if (f2==0)
  415.             return;
  416.         if (f1*f2==-1)
  417.             sort_x();
  418.         int dx,dy,ux,uy;
  419.         dx = abs(x2-x1);
  420.         dy = abs(y2-y1);
  421.         ux = getsign(x2-x1);
  422.         uy = getsign(y2-y1);
  423.         if (dx >= dy) {
  424.             int r = dx/2;
  425.             for (;;) {
  426.                 if (x1==x2) {
  427.                     f1=f2;
  428.                     break;
  429.                 }
  430.                 x1 += ux, r += dy;
  431.                 if (r >= dx) {
  432.                     r -= dx, y1 += uy;
  433.                     sort_x();
  434.                 }
  435.             }
  436.         } else {
  437.             int r = dy/2;
  438.             for (;;) {
  439.                 if (y1==y2) {
  440.                     f1=f2;
  441.                     break;
  442.                 }
  443.                 y1 += uy, r += dx;
  444.                 if (r >= dy)
  445.                     r -= dy, x1 += ux;
  446.                 sort_x();
  447.             }
  448.         }
  449.     }
  450.     for (i=0; i<pnum-1; i++)
  451.         makebuf(xlist[i],ylist[i],xlist[i+1],ylist[i+1]);
  452.     makebuf(xlist[pnum-1],ylist[pnum-1],xlist[0],ylist[0]);
  453.     // 領域バッファへの出力
  454.     for (i=0; i<areaylen; i++) {
  455.         int j;
  456.         for (j=0; j<XBUFMAX; j+=2) {
  457.             if (_max(xbuf[i][j],xbuf[i][j+1]) < areaxlen)
  458.                 area_hline(xbuf[i][j],xbuf[i][j+1],i);
  459.             else
  460.                 break;
  461.         }
  462.     }
  463. }
  464.  
  465.  
  466.  
  467.  
  468. int area_input(int type)
  469. // type  0=AREA_BOX  1=AREA_POLYGON
  470. // 返値: 0=承認  1=取消
  471. {
  472.     int lat2xlen, lat2ylen;
  473.     DMimage_getlatticesize(&lat2xlen,&lat2ylen);
  474.     area_clear();
  475.     if (type == AREA_BOX)
  476.     {
  477.         int step = 0;
  478.         int x1=0,y1=0,x2,y2;
  479.         void drawcsr(int msx,int msy)
  480.         {
  481.             if (step==1)
  482.             {
  483.                 int tx,ty;
  484.                 tx = DMimage_getx(msx),  ty = DMimage_gety(msy);
  485.                 int p1,p2,p3,p4;
  486.                 p1=x1,p2=y1,p3=tx,p4=ty;
  487.                 if (p1 > p3)
  488.                     swap(p1,p3);
  489.                 if (p2 > p4)
  490.                     swap(p2,p4);
  491.                 if (areaadj)
  492.                 {
  493.                     p1 = p1 - p1 % lat2xlen;
  494.                     p2 = p2 - p2 % lat2ylen;
  495.                     p3 = p3 - p3 % lat2xlen + lat2xlen - 1;
  496.                     p4 = p4 - p4 % lat2ylen + lat2ylen - 1;
  497.                     p3 = _min(p3,areaxlen-1);
  498.                     p4 = _min(p4,areaylen-1);
  499.                 }
  500.                 MOFF; EIMboxline(p1, p2, p3, p4, white, DrawXOR); MON;
  501.             }
  502.         }
  503.         pnum=-1;
  504.         for(;;)
  505.         {
  506.             int prex,prey;
  507.             if (step == 0 || areaadj)
  508.                 DMdispcsr(ms.x,ms.y);
  509.             drawcsr((prex=ms.x),(prey=ms.y));
  510.             do
  511.                 ms_get(&ms);
  512.             while (ms.dx==0 && ms.dy==0 && ms.btn1==OFF && ms.btn2==OFF &&
  513.                    key_chk()==0);
  514.             if (step == 0 || areaadj)
  515.                 DMerasecsr();
  516.             drawcsr(prex,prey);        // 消去
  517.             scrollForCsr(1,1);
  518.             if (ms.btn1==OFFON)
  519.             {
  520.                 if (step==0)             // 始点指定
  521.                     step=1, x1=DMimage_getx(ms.x), y1=DMimage_gety(ms.y);
  522.                 else if (step==1)         // 終点指定
  523.                 {
  524.                     x2=DMimage_getx(ms.x), y2=DMimage_gety(ms.y);
  525.                     if (x1 > x2)
  526.                         swap(x1,x2);
  527.                     if (y1 > y2)
  528.                         swap(y1,y2);
  529.                     if (areaadj)
  530.                     {
  531.                         x1 = x1 - x1 % lat2xlen;
  532.                         y1 = y1 - y1 % lat2ylen;
  533.                         x2 = x2 - x2 % lat2xlen + lat2xlen - 1;
  534.                         y2 = y2 - y2 % lat2ylen + lat2ylen - 1;
  535.                         x2 = _min(x2,areaxlen-1);
  536.                         y2 = _min(y2,areaylen-1);
  537.                     }
  538.                     int y;
  539.                     for (y=y1; y<=y2; y++)
  540.                         area_hline(x1,x2,y);
  541.                     ax1 = x1, ay1 = y1, ax2 = x2, ay2 = y2;
  542.                     return 0;
  543.                 }
  544.             }
  545.             if (ms.btn2==OFFON)
  546.             {
  547.                 if (step==0)
  548.                     return -1;
  549.                 else if (step==1)
  550.                     step=0;
  551.             }
  552.         }
  553.     }
  554.     else
  555.     {
  556.         bool first;
  557. POLY_RETRY:
  558.         pnum = 0;
  559.         px[0] = py[0] = -1;
  560.         ax1 = ay1 = 0xffff;
  561.         ax2 = ay2 = 0;
  562.         void drawcsr(int msx,int msy)
  563.         {
  564.             int tx,ty;
  565.             tx = DMimage_getx(msx),  ty = DMimage_gety(msy);
  566.             if (pnum > 0)
  567.             {
  568.                 int x1,y1;
  569.                 x1 = px[pnum-1], y1 = py[pnum-1];
  570.                 MOFF; EIMline(x1,y1,tx,ty,white,DrawXOR); MON;
  571.             }
  572.         }
  573.         first = YES;
  574.         for (;;)
  575.         {
  576.             int pre_x,pre_y;
  577.             DMdispcsr(ms.x, ms.y);
  578.             drawcsr(ms.x, ms.y);
  579.             pre_x = ms.x,  pre_y = ms.y;
  580.             do
  581.                 ms_get(&ms);
  582.             while (ms.dx == 0 && ms.dy == 0 &&
  583.                    ms.btn1 == OFF && ms.btn2 == OFF &&
  584.                    key_chk() == 0);
  585.             DMerasecsr();
  586.             drawcsr(pre_x, pre_y);    // 消去
  587.             scrollForCsr(1,1);
  588.             if ((ms.btn1 == OFFON || (ms.btn1 == ON && !first)) &&
  589.                 ms.btn2 == OFF)
  590.             {
  591.                 if (pnum < MAXP-1)
  592.                 {
  593.                     int tx,ty;
  594.  
  595.                     tx = DMimage_getx(ms.x),  ty = DMimage_gety(ms.y);
  596.                     if (pnum == 0 || tx!=px[pnum-1] || ty!=py[pnum-1])
  597.                     {
  598.                         if (tx < ax1)
  599.                             ax1 = tx;
  600.                         if (ax2 < tx)
  601.                             ax2 = tx;
  602.                         if (ty < ay1)
  603.                             ay1 = ty;
  604.                         if (ay2 < ty)
  605.                             ay2 = ty;
  606.                         px[pnum] = tx,  py[pnum] = ty;
  607.                         if (pnum >= 1)
  608.                         {
  609.                             int x1,y1,x2,y2;
  610.                             x1 = px[pnum-1], y1 = py[pnum-1];
  611.                             x2 = px[pnum  ], y2 = py[pnum  ];
  612.                             MOFF;
  613.                             EIMline(x1,y1,x2,y2,white,DrawXOR);
  614.                             EIMpset(x2,y2,white,DrawXOR);
  615.                             MON;
  616.                         }
  617.                         pnum++;
  618.                     }
  619.                 }
  620.             }
  621.             if (ms.btn1 == OFF || ms.btn1 == ONOFF)
  622.                 first = NO;
  623.             if (ms.btn2 == ONOFF)
  624.             {
  625.                 // ラバー表示を消す
  626.                 int i;
  627.                 for (i=1; i<pnum; i++)
  628.                 {
  629.                     int x1,y1,x2,y2;
  630.                     x1 = px[i-1], y1 = py[i-1];
  631.                     x2 = px[i  ], y2 = py[i  ];
  632.                     MOFF;
  633.                     EIMline(x1,y1,x2,y2,white,DrawXOR);
  634.                     EIMpset(x2,y2,white,DrawXOR);
  635.                     MON;
  636.                 }
  637.                 if (pnum == 0)
  638.                     goto POLY_CANCEL;
  639.                 else if (pnum >= 3 && (ms.btn1 == OFF || ms.btn1 == ONOFF))
  640.                     goto POLY_ACCEPTED;
  641.                 else
  642.                     goto POLY_RETRY;
  643.             }
  644.         }
  645. POLY_ACCEPTED:
  646.         px[pnum] = py[pnum] = -1;
  647.         if (pnum >= 3)
  648.             area_polygon(px,py);
  649.         return 0;
  650. POLY_CANCEL:
  651.         return -1;
  652.     }
  653. }
  654.  
  655.  
  656. void area_drawbound()
  657. {
  658.     if (pnum == -1)
  659.     {
  660.         MOFF; EIMboxline(ax1,ay1,ax2,ay2,white,DrawXOR); MON;
  661.     }
  662.     else if (pnum >= 3)
  663.     {
  664.         int i;
  665.         for (i=1; i<pnum; i++)
  666.         {
  667.             int x1,y1,x2,y2;
  668.             x1 = px[i-1], y1 = py[i-1];
  669.             x2 = px[i  ], y2 = py[i  ];
  670.             MOFF;
  671.             EIMline(x1,y1,x2,y2,white,DrawXOR);
  672.             EIMpset(x2,y2,white,DrawXOR);
  673.             MON;
  674.         }
  675.         MOFF;
  676.         EIMline(px[pnum-1],py[pnum-1],px[0],py[0],white,DrawXOR);
  677.         EIMpset(px[0],py[0],white,DrawXOR);
  678.         MON;
  679.     }
  680. }
  681.  
  682.  
  683. static char bit8[] = {1,2,4,8,16,32,64,128};
  684.  
  685.  
  686. bool area_chkxy(int x, int y)    // (x,y) が領域指定されているかを調べる
  687. {
  688.     if (x < 0 || y < 0 || areaxlen <= x || areaylen <= y)
  689.         return NO;
  690.     if (!areasizevar)
  691.     {
  692.         char r = (x & 7);
  693.         return (*(area_buf+y*(AREAXLEN/8)+(x>>3)) & bit8[r]) == 0 ? NO : YES;
  694.     }
  695.     else
  696.     {
  697.         char r = (x & 7);
  698.         return (*(area_buf+y*(areaxlen>>3)+(x>>3)) & bit8[r]) == 0 ? NO : YES;
  699.     }
  700. }
  701.  
  702.  
  703. bool area_chkxy2(int x,int y)    // (x,y)-(x+1,y+1)が領域指定されているか
  704. {
  705.     if (x+1 < 0 || y+1 < 0 || areaxlen <= x || areaylen <= y)
  706.         return NO;
  707.     char *p;
  708.     int xsize;
  709.     if (!areasizevar)
  710.         p = area_buf+y*(AREAXLEN/8)+(x>>3), xsize = AREAXLEN;
  711.     else
  712.         p = area_buf+y*(areaxlen>>3)+(x>>3), xsize = areaxlen;
  713.     int r = (x & 7);
  714.     if (0 <= y)
  715.     {
  716.         if (0 <= x)
  717.         {
  718.             if ((*p & bit8[r]) != 0)
  719.                 return YES;
  720.         }
  721.         if (x+1 < xsize)
  722.         {
  723.             if (r == 7)
  724.                 { if ((*(p+1) & bit8[0]) != 0)  return YES; }
  725.             else
  726.                 { if ((*p & bit8[r+1]) != 0)  return YES; }
  727.         }
  728.     }
  729.     if (y+1 < areaylen)
  730.     {
  731.         p += (xsize>>3);
  732.         if (0 <= x)
  733.         {
  734.             if ((*p & bit8[r]) != 0)
  735.                 return YES;
  736.         }
  737.         if (x+1 < xsize)
  738.         {
  739.             if (r == 7)
  740.                 { if ((*(p+1) & bit8[0]) != 0)  return YES; }
  741.             else
  742.                 { if ((*p & bit8[r+1]) != 0)  return YES; }
  743.         }
  744.     }
  745.     return NO;
  746. }
  747.  
  748.  
  749. int area_chkxylen(int x,int xmax,int y,bool nega)
  750. // (x,y) から右に何ドット連続して指定されているかを調べる(or 0)
  751. // nega: 働きを逆にする(領域指定されていない点の連続数を求める)
  752. {
  753.     int _maxx = _min(xmax,areaxlen-1);
  754.     if (x > _maxx)
  755.         return 0;
  756.     int xbytes = areaxlen >> 3;
  757.     char *p = area_buf + y*xbytes + (x>>3);
  758.     int i,r;
  759.     if (!nega)
  760.     {
  761.         for (i=x,r=x&7; i<=_maxx; )
  762.         {
  763.             if (r==0 && *p == 255)
  764.             {
  765.                 i+=8, p++;
  766.                 continue;
  767.             }
  768.             else if ((*p & bit8[r]) == 0)
  769.                 break;
  770.             i++;
  771.             if (++r == 8)
  772.                 r=0, p++;
  773.         }
  774.     }
  775.     else
  776.     {
  777.         for (i=x,r=x&7; i<=_maxx; )
  778.         {
  779.             if (r==0 && *p == 0)
  780.             {
  781.                 i+=8, p++;
  782.                 continue;
  783.             }
  784.             else if ((*p & bit8[r]) != 0)
  785.                 break;
  786.             i++;
  787.             if (++r == 8)
  788.                 r=0, p++;
  789.         }
  790.     }
  791.     i = _min(_maxx+1, i);
  792.     return i-x;
  793. }
  794.  
  795.  
  796. void area_getboundxy(int *x1, int *y1, int *x2, int *y2)
  797. // 領域指定された部分を囲む矩形を取得
  798. {
  799.     *x1 = ax1;
  800.     *y1 = ay1;
  801.     *x2 = ax2;
  802.     *y2 = ay2;
  803. }
  804.  
  805.  
  806. /*--------------------------------------------------------*/
  807. /*         INT 23h, 24h の割り込みハンドラの登録          */
  808. /*          High-C 割り込み処理のサンプルより             */
  809. /*--------------------------------------------------------*/
  810.  
  811.  
  812. typedef struct {
  813.     int selecter ;    // native vector selecter
  814.     int offset ;    // native vector offset
  815.     int real_vect ;    // real vector
  816. } vector_t ;
  817.  
  818. static vector_t    int23, int24 ;  // 過去のベクタの退避用
  819.  
  820. #pragma Calling_convention( C_interrupt ) ; /*  割り込みルーチン開始  */
  821.  
  822. static void int23h( Machine_status Stat )
  823. {
  824.     Stat.Flags = Stat.Flags ;   /*  dummy  */
  825.     return ;                    /*  iret  */
  826. }
  827.  
  828. static void int24h( Machine_status Stat )
  829. {
  830.     Stat.AX = 3 ;               /*  system call fault  */
  831.     return ;                    /*  iret  */
  832. }
  833.  
  834. #pragma Calling_convention() ;              /*  割り込みルーチン終了  */
  835.  
  836. static void dos_extender_call( int interrupt, int param )
  837. {
  838.     Registers.DS.W = getds() ;
  839.     Registers.AX.W = interrupt ;
  840.     Registers.CX.W = param ;
  841.     calldos() ;
  842. }
  843.  
  844. void ARTsetintvector( void )
  845. // int 23h/24h の割り込みベクタを int23h()/int24h() に変更
  846. {
  847.     union {
  848.         _far void (*ptr)() ;
  849.         struct {  unsigned int off ;  unsigned short seg ;  }  reg ;
  850.     } farptr23h, farptr24h ;
  851.  
  852.     /*  int 23h の退避  */
  853.     dos_extender_call( 0x2502, 0x0023 ) ;
  854.     int23.selecter = Registers.ES.W;
  855.     int23.offset = Registers.BX.R ;
  856.  
  857.     dos_extender_call( 0x2503, 0x0023 ) ;
  858.     int23.real_vect = Registers.BX.R ;
  859.  
  860.     farptr23h.ptr = (_far void (*)())int23h ;
  861.     Registers.DS.W = farptr23h.reg.seg ;
  862.     Registers.AX.W = 0x2506 ;
  863.     Registers.CX.W = 0x0023 ;
  864.     Registers.DX.R = farptr23h.reg.off ;
  865.     calldos() ;
  866.  
  867.     /*  int 24h の退避  */
  868.     dos_extender_call( 0x2502, 0x0024 ) ;
  869.     int24.selecter = Registers.ES.W ;
  870.     int24.offset = Registers.BX.R ;
  871.  
  872.     dos_extender_call( 0x2503, 0x0024 ) ;
  873.     int24.real_vect = Registers.BX.R ;
  874.  
  875.     // 割り込みベクタの設定(AX=2506H)
  876.     farptr24h.ptr = (_far void (*)())int24h ;
  877.     Registers.DS.W = farptr24h.reg.seg ;
  878.     Registers.AX.W = 0x2506 ;
  879.     Registers.CX.W = 0x0024 ;
  880.     Registers.DX.R = farptr24h.reg.off ;
  881.     calldos() ;
  882. }
  883.  
  884. void ARTresetintvector( void )
  885. // int 23h/24h の割り込みベクタを元に戻す
  886. {
  887.     /*  int 23h の復帰  */
  888.     Registers.AX.W = 0x2507 ;
  889.     Registers.CX.W = 0x0023 ;
  890.     Registers.DS.W = int23.selecter ;
  891.     Registers.DX.R = int23.offset ;
  892.     Registers.BX.R = int23.real_vect ;
  893.     calldos() ;
  894.  
  895.     /*  int 24h の復帰  */
  896.     Registers.AX.W = 0x2507 ;
  897.     Registers.CX.W = 0x0024 ;
  898.     Registers.DS.W = int24.selecter ;
  899.     Registers.DX.R = int24.offset ;
  900.     Registers.BX.R = int24.real_vect ;
  901.     calldos() ;
  902. }
  903.  
  904.  
  905. /*--------------------------------------------------------*/
  906. /*                      三角関数処理                      */
  907. /*--------------------------------------------------------*/
  908.  
  909. #if 0
  910.     deci *atan512_tbl;
  911. #endif
  912.  
  913. int mathtbl_init(void)
  914. {
  915. #if 0
  916.     if ((atan512_tbl = (deci*)malloc(sizeof(deci)*(DUNIT+1))) == NULL)
  917.     {
  918.         return -1;
  919.     }
  920.     int i;
  921.     for (i=0; i<=DUNIT; i++)
  922.         atan512_tbl[i] = FD(atan((double)i / DUNIT) * 512.0 / (2*_PI));
  923. #endif
  924.     return 0;
  925. }
  926.  
  927. deci atan512(int theta)
  928. {
  929. #if 0
  930.     if (theta > DUNIT)
  931.         theta = DUNIT;
  932.     else if (theta < 0)
  933.         theta = 0;
  934.     return atan512_tbl[theta];
  935. #else
  936.     return 0;
  937. #endif
  938. }
  939.  
  940. #if 0
  941.  
  942. static    int        *__sin, *__cos;
  943.  
  944.  
  945. int math32_init(void)
  946. {
  947.     char *p;
  948.     if ((p = malloc(sizeof(int)*
  949.     
  950. }
  951.  
  952.  
  953. void math32_end(void)
  954. {
  955. }
  956.  
  957. #endif
  958.  
  959.  
  960. void hline_func(int x1, int x2, int y, void func(int x1, int x2, int y)!)
  961. {
  962.     int ix = x1;
  963.     while (ix <= x2)
  964.     {
  965.         int l1 = mask_chkxylen(ix,x2,y,NO);
  966.         ix += l1;
  967.         if (ix > x2)
  968.             break;
  969.         int l2 = mask_chkxylen(ix,x2,y,YES);
  970.         if (l2 > 0)
  971.             func(ix,ix+l2-1,y);
  972.         ix += l2;
  973.         if (l1 <= 0 && l2 <=0)
  974.             break;
  975.     }
  976. }
  977.  
  978. /* end of sub.c */
  979.